<?php
/**
 * TotalService.php
 * 通过hook将改类替换系统原来的TotalService类
 *
 * @copyright  2023 beikeshop.com - All Rights Reserved
 * @link       https://beikeshop.com
 * @author     TL <mengwb@guangda.work>
 * @created    2023-05-12 17:11:31
 * @modified   2023-05-12 17:11:31
 */

namespace Plugin\MultiSeller\Services;

use Beike\Libraries\Tax;
use Beike\Shop\Services\CheckoutService;
use Illuminate\Support\Str;

class TotalService extends \Beike\Shop\Services\TotalService
{
    public function __construct($currentCart, $cartProducts)
    {
        $this->currentCart  = $currentCart;
        $this->cartProducts = ShopService::cartListGroupBySeller($cartProducts);
        $this->cartProducts = array_column($this->cartProducts, null, 'seller_id');
        $this->setShippingMethod($currentCart->shipping_method_code);
        $this->getTaxes();
    }

    /**
     * 获取税费数据
     *
     * @return array
     */
    public function getTaxes(): array
    {
        $addressInfo = [
            'shipping_address' => $this->currentCart->shippingAddress ?? $this->currentCart->guest_shipping_address,
            'payment_address'  => $this->currentCart->paymentAddress  ?? $this->currentCart->guest_payment_address,
        ];
        $taxLib = Tax::getInstance($addressInfo);

        foreach ($this->cartProducts as $sellerId => $sellerCartProduct) {
            $this->taxes[$sellerId] = [];
            foreach ($sellerCartProduct['list'] as $product) {
                if (empty($product['tax_class_id'])) {
                    continue;
                }

                $taxRates = $taxLib->getRates($product['price'], $product['tax_class_id']);
                foreach ($taxRates as $taxRate) {
                    if (! isset($this->taxes[$sellerId][$taxRate['tax_rate_id']])) {
                        $this->taxes[$sellerId][$taxRate['tax_rate_id']] = ($taxRate['amount'] * $product['quantity']);
                    } else {
                        $this->taxes[$sellerId][$taxRate['tax_rate_id']] += ($taxRate['amount'] * $product['quantity']);
                    }
                }
            }
        }

        return $this->taxes;
    }

    /**
     * @param CheckoutService $checkout
     * @return array
     */
    public function getTotals(CheckoutService $checkout): array
    {
        $maps = $this->getTotalClassMaps();
        foreach ($maps as $service) {
            if (! class_exists($service) || ! method_exists($service, 'getTotal')) {
                continue;
            }
            $service::getTotal($checkout);
        }

        return hook_filter('service.total.totals', $this->totals);
    }

    /**
     * total 与类名 映射
     *
     * @return mixed
     */
    private function getTotalClassMaps()
    {
        $maps = [];
        foreach (self::TOTAL_CODES as $code) {
            $serviceName  = Str::studly($code) . 'Service';
            $maps[$code]  = "\\Plugin\\MultiSeller\\Services\\TotalServices\\{$serviceName}";
        }

        $maps                = hook_filter('service.total.maps', $maps);
        $maps['order_total'] = '\\Plugin\\MultiSeller\\Services\\TotalServices\\OrderTotalService';

        return $maps;
    }

    /**
     * 获取当前购物车商品总额
     *
     * @param $sellerId null代表所有商户商品
     * @return mixed
     */
    public function getSubTotal(int|null $sellerId = null): mixed
    {
        if ($sellerId === null) {
            $subTotal = 0;
            foreach ($this->cartProducts as $products) {
                $subTotal += collect($products['list'])->sum('subtotal');
            }

            return $subTotal;
        }
        $carts = $this->cartProducts[$sellerId]['list'];

        return collect($carts)->sum('subtotal');
    }

    /**
     * @return array
     */
    public function getSellerIds(): array
    {
        return array_keys($this->cartProducts);
    }
}
